import axios from 'axios'

export const BASE_URL = 'http://localhost:3000/fhc'
// 是否正在刷新的标记
let isRefreshing = false
// 重试队列，每一项将是一个待执行的函数形式
let requests: any[] = []

// 创建一个实例
const service = axios.create({
  baseURL: BASE_URL,
  timeout: 5000 // request timeout
})

// 从localStorage中获取token
function getLocalToken() {
  const token = window.localStorage.getItem('token')
  return token
}

// 给实例添加一个setToken方法，用于登录后将最新token动态添加到header，同时将token保存在localStorage中
function setToken(token: string) {
  service.defaults.headers['token'] = token
  service.defaults.headers['Authorization'] = token
  window.localStorage.setItem('token', token)
}

//获取新的token请求
function refreshToken() {
  return service.get('/user/retoken').then((res: any) => res)
}

// 拦截请求
service.interceptors.request.use(
  function (config: any) {
    if (!config.url.endsWith('/user/login')) {
      config.headers.token = getLocalToken()
    }
    return config
  },
  function (error: any) {
    return Promise.reject(error)
  }
)

// 拦截返回的数据
service.interceptors.response.use(
  async function (response: any) {
    // 接下来会在这里进行token过期的逻辑处理
    // const { code } = response.data
    const request = response.request
    const responseType = request.responseType

    console.log('responseType', responseType)

    if (responseType && 'blob' == responseType) {
      const contextType = request.response.type
      console.log('contextType', contextType)
      if (contextType === 'application/json') {
        const reader = new FileReader()
        // 开始读取Blob数据
        reader.readAsText(response.data)
        // 读取Blob内容并将其转换为字符串
        // reader.onloadend = async () => {
        //   const resultString = reader.result // 获得转换后的字符串结果
        //   console.log('FileReader', resultString)
        // }
        await new Promise((resolve, reject) => {
          reader.onloadend = resolve
          reader.onerror = reject
        })
        console.log('reader.result', reader.result)
        const rep: { code: number; message: string; data: Record<string, any> } = JSON.parse(
          reader.result as string
        )
        return rep
      } else {
        return response
      }
    }
    const responseURL: string = request.responseURL
    const rep: { code: number; message: string; data: Record<string, any> } = JSON.parse(
      request.responseText
    )

    if (responseURL.endsWith('/user/retoken')) {
      isRefreshing = false
    }
    if (responseURL.endsWith('/user/login')) {
      const { code, data } = rep
      console.error('error', code, data)
      if (code == 200 || code == 0) {
        window.localStorage.setItem('token', data.token)
      }
    }
    console.log('response:', response.data, rep)
    return response.data
  },
  async (error: any) => {
    if (error.code == 'ERR_NETWORK' || error.code == 'ECONNABORTED') {
      isRefreshing = false
      console.error('>>>>>>', error.code)
      // window.location.href = '/socket'
      return Promise.reject(error)
    }
    const response = error.response
    const request = response.request
    const responseURL: string = request.responseURL
    console.log('error response:', responseURL)
    if (responseURL.endsWith('/user/retoken')) {
      isRefreshing = false
    }

    // const { code } = response.data
    // 说明token过期了,获取新的token
    if (response.status === 401) {
      const oldToken = getLocalToken()
      console.log('oldToken:', oldToken, isRefreshing)
      if (!oldToken) {
        isRefreshing = false
        // window.location.href = '/socket'
        return Promise.reject(error)
      }
      const config = response.config
      //判断一下状态
      if (!isRefreshing) {
        //修改状态，进入更新token阶段
        isRefreshing = true
        // 获取当前的请求
        const resToken = await refreshToken()
        console.log(resToken)
        const { code, data } = resToken
        if (code === 200 || code === 0) {
          setToken(data.token)
          //重置失败请求的配置
          config.headers['Authorization'] = data.token
          config.headers['token'] = data.token

          //已经刷新了token，将所有队列中的请求进行重试
          requests.forEach((cb) => cb(data.token))
          // 重试完了别忘了清空这个队列
          requests = []
          //重试当前请求并返回promise
          return service(config)
        } else {
          isRefreshing = false
          console.log('重新请求token失败，跳转到登录页')
          // window.location.href = '/socket'
        }
        isRefreshing = false
      } else {
        // 正在刷新token，返回一个未执行resolve的promise
        return new Promise((resolve) => {
          // 将resolve放进队列，用一个函数形式来保存，等token刷新后直接执行
          requests.push((token: string) => {
            config.headers['Authorization'] = token
            config.headers['token'] = token
            resolve(service(config))
          })
        })
      }
    } else {
      return Promise.reject(error)
    }
  }
)
//暴露
export default service
